package fr.mmt.gisfizz.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import fr.mmt.gisfizz.entity.User;
import fr.mmt.gisfizz.service.UserCrudService;
import java.io.IOException;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@Slf4j
public class UserHandler implements CrudHandler<User, String> {

    @Resource
    private UserCrudService userCrudService;

    /**
     * {@inheritDoc}
     */
    @Override
    @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
    public @ResponseBody
    User get(HttpServletRequest request, final HttpServletResponse response, @PathVariable String id) {
        if (StringUtils.isBlank(id)) {
            log.info("getSingle : id is undefined");
            return null;
        }
        log.info("get {}", id);
        return userCrudService.getByPk(id);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public @ResponseBody
    Page<User> search(HttpServletRequest request, final HttpServletResponse response, String search, Integer page, Integer size, String sortColumn, String sortDirection) {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, String> searchMap;
        try {
            searchMap = mapper.readValue(search, Map.class);
        } catch (IOException ex) {
            log.warn(ex.getMessage());
            return null;
        }
        if (null == page || null == size) {
            return userCrudService.search(searchMap, new PageRequest(0, Integer.MAX_VALUE));
        } else {
            return userCrudService.search(searchMap, new PageRequest(page, size));
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @RequestMapping(value = "/users", headers = {"!X-HTTP-Method-Override"}, method = RequestMethod.POST)
    public @ResponseBody
    User create(HttpServletRequest request, final HttpServletResponse response, @RequestBody User newObj) {
        if (StringUtils.isNotBlank(newObj.getId())) {
            return null;
        }
        log.info("create {}", newObj);
        userCrudService.save(newObj);
        return newObj;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @RequestMapping(value = "/users/{id}", headers = {"X-HTTP-Method-Override=DELETE"}, method = RequestMethod.POST)
    public void delete(HttpServletRequest request, final HttpServletResponse response, @PathVariable String id) {
        if (StringUtils.isBlank(id)) {
            return;
        }
        log.info("delete {}", id);
        userCrudService.delete(id);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @RequestMapping(value = "/users/{id}", headers = {"X-HTTP-Method-Override=PUT"}, method = RequestMethod.POST)
    public @ResponseBody
    User update(HttpServletRequest request, final HttpServletResponse response, @RequestBody User updObj, @PathVariable String id) {
        if (!StringUtils.equals(updObj.getId(), id)) {
            return null;
        }
        log.info("update {}", updObj);
        userCrudService.save(updObj);
        return updObj;
    }
}
